package com.navinfo.tripanalysis.common.fuelleak;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.navinfo.tripanalysis.common.util.GsonUtils;
import com.navinfo.tripanalysis.common.util.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 漏油高发地信息全部放入Redis中，从Redis中读取
 * @author CAI.HS
 */
public class FuelLeakServiceImpl implements FuelLeakService {
    private static Logger logger = LoggerFactory.getLogger(FuelLeakServiceImpl.class);

    /**
     * 缓存前缀
     */
    private static final String KEY_PREFIX = "leakoil";

    /**
     * Redis缓存
     */
    private RedisUtils redisCache;
    /**
     * 本地缓存
     */
    private LoadingCache<Long, FuelLeakLocation> localCache;

    @Override
    public void init(Map map) throws Exception {
        RedisUtils.buildInstance(map);
        redisCache = RedisUtils.getInstance();
        localCache = Caffeine.newBuilder()
                .refreshAfterWrite(Integer.parseInt(String.valueOf(map.get("vehicleInfo.Syn.Time"))), TimeUnit.HOURS)
                .initialCapacity(Integer.parseInt(String.valueOf(map.get("vehicleInfo.initialCapacity"))))
                .build(key -> getFuelLeakLocation(key));
    }

    @Override
    public FuelLeakLocation get(long tileId) {
        FuelLeakLocation location = null;
        try {
            location = localCache.get(tileId);
        } catch (Exception e) {
            logger.error("获取漏油高发地信息错误：" + tileId, e);
        }
        return location;
    }

    @Override
    public void put(long tileId, String subKey, Object value) {
        redisCache.setHashValue(getKey(tileId), subKey, GsonUtils.gsonString(value));
    }

    @Override
    public void reload(long tileId){
        //从redis中获取最新的信息
        localCache.invalidate(tileId);
    }

    /**
     * 从redis中查询车辆信息保存到本地缓存中
     * 设置最后更新时间
     * @param tid 瓦片ID
     * @return
     */
    private FuelLeakLocation getFuelLeakLocation(long tid) {
        Map<String, String> map = redisCache.getHashValueAll(getKey(tid));
        String jsonStr = GsonUtils.gsonString(map);

        FuelLeakLocation result = null;

        if (StringUtils.isNotEmpty(jsonStr)) {
            result = GsonUtils.gsonToBean(jsonStr, FuelLeakLocation.class);
            // redis的value没有存terminalId
            // 所以这里需要设置一下
            logger.debug("获取漏油高发地信息成功：" + tid);
        }

        if (result == null) {
            logger.debug("不是漏油高发地：" + tid);
        }

        return result;
    }

    /**
     * 获取Redis中缓存的key
     * @param tileId 瓦片ID
     * @return
     */
    private String getKey(long tileId) {
        return String.format("%s_%d", KEY_PREFIX, tileId);
    }

}
